package com.langll.ai.tool;

import io.micrometer.observation.ObservationRegistry;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.tool.DefaultToolCallingManager;
import org.springframework.ai.model.tool.ToolCallingManager;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbacks;
import org.springframework.ai.tool.execution.DefaultToolExecutionExceptionProcessor;
import org.springframework.ai.tool.execution.ToolExecutionExceptionProcessor;
import org.springframework.ai.tool.resolution.DelegatingToolCallbackResolver;
import org.springframework.ai.tool.resolution.StaticToolCallbackResolver;
import org.springframework.ai.tool.resolution.ToolCallbackResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;

/**
 * 自定义 tool 配置
 */
@Configuration
public class CustomToolManager {

    /**
     * tool 调用过程管理
     */
    @Bean
    ToolCallingManager toolCallingManager() {
//        return ToolCallingManager.builder().build();
        FunctionCallback[] dateTimeTools = ToolCallbacks.from(new DateTimeTools());
        List<FunctionCallback> toolCallbackList = Arrays.asList(dateTimeTools);
        return new DefaultToolCallingManager(
                ObservationRegistry.NOOP,
                toolCallbackResolver(toolCallbackList),
                toolExecutionExceptionProcessor());
    }

    /**
     * 工具调用列表
     * @return
     */
    ToolCallbackResolver toolCallbackResolver(List<FunctionCallback> toolCallbacks) {
        StaticToolCallbackResolver staticToolCallbackResolver = new StaticToolCallbackResolver(toolCallbacks);
        return new DelegatingToolCallbackResolver(List.of(staticToolCallbackResolver));
    }

    /**
     * 异常处理
     * @return
     */
    ToolExecutionExceptionProcessor toolExecutionExceptionProcessor() {
        //true 错误不发送给模型，false 错误发给模型分析
        return new DefaultToolExecutionExceptionProcessor(true);
    }


}
